#include "SceneryFactory.h";


SceneryFactory::SceneryFactory(void)
{
}

//----------------------------------------------------------------------------------------------------------------


SceneryFactory::~SceneryFactory(void)
{
}

//----------------------------------------------------------------------------------------------------------------


ActorEntitySceneNode *SceneryFactory::createScenery(WorldEnums::eSceneryObjects sceneryType, Ogre::String uniqeId, NxOgre::Vec3 position, NxOgre::Scene* mScene, Ogre::SceneManager *mSceneMgr)
{
	switch(sceneryType)
	{
	case WorldEnums::Scenery_Block1:
			return createBoxStaticActor(sceneryType, uniqeId.append(":Scenery_Block1"), "Block.mesh", Ogre::Vector3(0.006, 0.006, 0.006), NxOgre::Vec3(0.5, 0.5, 0.2), position,0.5, mScene, mSceneMgr);
	break;
	case WorldEnums::Scenery_Block2:
			return createBoxStaticActor(sceneryType, uniqeId.append(":Scenery_Block2"), "Block2.mesh", Ogre::Vector3(0.01, 0.01, 0.01), NxOgre::Vec3(1.6, 1.4, 0.6), position, 0, mScene, mSceneMgr);
	break;
	case WorldEnums::Scenery_Block3:
			return createBoxStaticActor(sceneryType, uniqeId.append(":Scenery_Block3"), "Block3.mesh", Ogre::Vector3(0.006, 0.006, 0.006), NxOgre::Vec3(0.7, 0.9, 0.4), position, 0, mScene, mSceneMgr);
	break;
	case WorldEnums::Scenery_House1:
			return createBoxStaticActor(sceneryType, uniqeId.append(":Scenery_House1"), "House.mesh", Ogre::Vector3(0.004, 0.004, 0.004), NxOgre::Vec3(0.2, 0.2, 0.2), position,0.18, mScene, mSceneMgr);
	break;
	case WorldEnums::Scenery_House2:
			return createBoxStaticActor(sceneryType, uniqeId.append(":Scenery_House2"), "House2.mesh", Ogre::Vector3(0.004, 0.004, 0.004), NxOgre::Vec3(0.2, 0.2, 0.2), position, 0.18, mScene, mSceneMgr);
	break;
	case WorldEnums::Scenery_Tree1:
			return createGraphicalActor(sceneryType, false, uniqeId.append(":Scenery_Tree1"), "tree1.mesh", Ogre::Vector3(0.001, 0.001, 0.001), Ogre::Vector3(position.x,position.y,position.z), 0, mSceneMgr);
	break;
	case WorldEnums::Scenery_Tree2:
			return createGraphicalActor(sceneryType, false, uniqeId.append(":Scenery_Tree2"), "tree2.mesh", Ogre::Vector3(0.001, 0.001, 0.001), Ogre::Vector3(position.x,position.y,position.z), 0, mSceneMgr);
	break;
	case WorldEnums::Scenery_Lake1:
			return createGraphicalActor(sceneryType, true, uniqeId.append(":Scenery_Lake1"), "Water_surface.mesh", Ogre::Vector3(0.01, 0.01, 0.01), Ogre::Vector3(position.x,position.y,position.z), 0, mSceneMgr);
	break;
	case WorldEnums::Scenery_Lake2:
			return createGraphicalActor(sceneryType, true, uniqeId.append(":Scenery_Lake2"), "Water_surface2.mesh", Ogre::Vector3(0.01, 0.01, 0.01), Ogre::Vector3(position.x,position.y,position.z), 0, mSceneMgr);
	break;
	case WorldEnums::Scenery_Lake3:
			return createGraphicalActor(sceneryType, true, uniqeId.append(":Scenery_Lake3"), "Water_surface3.mesh", Ogre::Vector3(0.01, 0.01, 0.01), Ogre::Vector3(position.x,position.y,position.z), 0, mSceneMgr);
	break;
	}
}

//----------------------------------------------------------------------------------------------------------------

ActorEntitySceneNode *SceneryFactory::createBoxStaticActor(WorldEnums::eSceneryObjects sceneryType, Ogre::String actorName, Ogre::String meshName, Ogre::Vector3 meshScale, NxOgre::Vec3 collisionBoxSizes, NxOgre::Vec3 position, Ogre::Real heightCorrection, NxOgre::Scene* mScene, Ogre::SceneManager *mSceneMgr)
{
	NxOgre::RigidBodyDescription bodyDescription;
	bodyDescription.mMass = 10000.0f; 

	std::cout << "\ncreateSceneGeometry";	
	NxOgre::SceneGeometry *staticObject = mScene->createSceneGeometry(NxOgre::BoxDescription(collisionBoxSizes.x,collisionBoxSizes.y,collisionBoxSizes.z), NxOgre::Vec3(position.x, position.y + (collisionBoxSizes.y/2), position.z), bodyDescription);
	
	Ogre::SceneNode* mActorNode;
	Ogre::Entity* mActorEntity;

	std::cout << "\ncreateEntity with meshName:" << meshName.data();	
	mActorEntity = mSceneMgr->createEntity(meshName);

	std::cout << "\ncreateSceneNode";	
	mActorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    mActorNode->attachObject(mActorEntity);
	mActorNode->setScale(meshScale);
	mActorNode->setPosition(position.x,position.y+heightCorrection,position.z);
	mActorEntity->setCastShadows(true);

    //hard coded corrections
	//the house meshes has wrong orientation, they have to be rotated
	if((meshName == "House.mesh")||(meshName == "House2.mesh"))
	{
		mActorNode->rotate(Ogre::Vector3(1,0,0),Ogre::Degree(90));
	}

	ActorEntitySceneNode *actor = new ActorEntitySceneNode(sceneryType,actorName,staticObject,mActorNode,mActorEntity);
	staticObject->setContactCallback(actor);
	actor->isPhisical = true;

	return actor;
}

//-----------------------------------------------------------------------------------------------------------------


ActorEntitySceneNode *SceneryFactory::createGraphicalActor(WorldEnums::eSceneryObjects sceneryType, bool isHolderActor, Ogre::String actorName, Ogre::String meshName, Ogre::Vector3 meshScale, Ogre::Vector3 position, Ogre::Real heightCorrection, Ogre::SceneManager *mSceneMgr)
{
	Ogre::SceneNode* mActorNode;
	Ogre::Entity* mActorEntity;

	std::cout << "\ncreateEntity with meshName:" << meshName.data();	
	mActorEntity = mSceneMgr->createEntity(meshName);

	std::cout << "\ncreateSceneNode";	
	mActorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    mActorNode->attachObject(mActorEntity);
	mActorNode->setScale(meshScale);
	mActorNode->setPosition(position.x,position.y+heightCorrection,position.z);
	if((meshName == "Water_surface.mesh")||(meshName == "Water_surface2.mesh")||(meshName == "Water_surface3.mesh"))
	{
		mActorEntity->setCastShadows(false);
	}
	else
	{
		mActorEntity->setCastShadows(true);
	}


	if(isHolderActor)
	{
		Lake *holderActor = new Lake(sceneryType,actorName,10000,0,mActorNode,mActorEntity);
		holderActor->isPhisical = false;

		return holderActor;
	}
	else
	{
		ActorEntitySceneNode *actor = new ActorEntitySceneNode(sceneryType, actorName,0,mActorNode,mActorEntity);
		actor->isPhisical = false;

		return actor;
	}
}


//-----------------------------------------------------------------------------------------------------------------